package com.ecust.ml.cardriving.view;

import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.Timer;

import com.ecust.ml.cardriving.controller.CarDriverController;
import com.ecust.ml.cardriving.model.Car;
import com.ecust.ml.cardriving.model.Highway;

public class CarDrivingSimulator extends JFrame{

	private static final long serialVersionUID = -1044031044085024089L;
	
	public static final int HEIGHT = 600;
	public static final int WIDTH = 600;
	public static final int DATA_COLLECTION_INTERVAL = 100;
	public static final int RENDER_INTERVAL = 100;
	
	private Timer timer = new Timer(DATA_COLLECTION_INTERVAL, new ActionListener() {
		
		@Override
		public void actionPerformed(ActionEvent e) {
			cdc.run();
			highwayViewer.repaint();
		}
	});
	
	private Timer trainTimer = new Timer(1000, new ActionListener() {
		
		@Override
		public void actionPerformed(ActionEvent e) {
			timeValue.setText(trainSeconds++ +"s");
		}
	});
	
	public static int trainSeconds = 0;
	private JLabel timeValue = new JLabel(trainSeconds+"s");
	
	private HighwayViewer highwayViewer;
	
	private CarDriverController cdc;
	
	private Car targetCar;
	
	public CarDrivingSimulator() {
		
		// 基本信息
		Highway highway = new Highway();
		targetCar = new Car(Highway.LANE_MIDDLE, Car.SPEED_INIT, Car.CAR_RUN_POSITION);
		highwayViewer = new HighwayViewer(highway, targetCar, "跟踪视角");
		cdc = new CarDriverController(highway, highwayViewer, targetCar);
		
		// 布局
		setLayout(new GridLayout(1,2));
		// 组件
		JPanel rightPanel = new JPanel();
		rightPanel.setLayout(new FlowLayout());
		
		// 速度按钮
		JButton speed0 = new JButton("0 km/h");
		JButton speed35 = new JButton("35 km/h");
		JButton speed65 = new JButton("65 km/h");
		JButton speed100 = new JButton("100 km/h");
		// 按钮监听
		speed0.addMouseListener(new SpeedButtonMouseAdapter(0));
		speed35.addMouseListener(new SpeedButtonMouseAdapter(35));
		speed65.addMouseListener(new SpeedButtonMouseAdapter(65));
		speed100.addMouseListener(new SpeedButtonMouseAdapter(100));
		rightPanel.add(speed0);
		rightPanel.add(speed35);
		rightPanel.add(speed65);
		rightPanel.add(speed100);
		
		// 视角按钮
		JButton viewNormal = new JButton("普通视角");
		JButton viewFollow = new JButton("跟踪视角");
		viewNormal.addMouseListener(new ViewButtonAdapter("正常"));
		viewFollow.addMouseListener(new ViewButtonAdapter("跟踪"));
		// 按钮监听
		rightPanel.add(viewNormal);
		rightPanel.add(viewFollow);
		
		// 训练/自动驾驶
		final JToggleButton trainModeToggle= new JToggleButton("训练模式");
		final JToggleButton autoModeToggle = new JToggleButton("自动模式");
		JLabel timeLabel = new JLabel("训练时间");
		trainModeToggle.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                if(trainModeToggle.isSelected()) {
                	CarDriverController.trainMode = true;
                	trainTimer.start();
                } else {
                	if(CarDriverController.trainMode) {
                		cdc.writeTrainingDataToFile();
                		trainTimer.stop();
                		trainSeconds=0;
                		timeValue.setText(trainSeconds +"s");
                	}
                	CarDriverController.trainMode = false;
                }
                recoverFocus();
            }
        });
		autoModeToggle.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                if(autoModeToggle.isSelected()) {
                	CarDriverController.autoMode = true;
                } else {
                	CarDriverController.autoMode = false;
                }
                recoverFocus();
            }
        });
		rightPanel.add(trainModeToggle);
		rightPanel.add(autoModeToggle);
		rightPanel.add(timeLabel);
		rightPanel.add(timeValue);
		
		// 重新开始
		JButton restartButton = new JButton("重新开始");
		restartButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				cdc.cleanCarsOnRoad();
				recoverFocus();
			}
		});
		rightPanel.add(restartButton);
		
        add(highwayViewer);
        add(rightPanel);
		
        // 监听器
        this.addKeyListener(new KeyAdapter() {
        	public void keyPressed(KeyEvent evt) {
        		if(evt.getKeyCode() == KeyEvent.VK_LEFT) {
        			cdc.turnLeft();
        		} else if(evt.getKeyCode() == KeyEvent.VK_RIGHT){
        			cdc.turnRight();
        		} else if(evt.getKeyCode() == KeyEvent.VK_UP){
        			targetCar.speedUp();
        		} else if(evt.getKeyCode() == KeyEvent.VK_DOWN){
        			targetCar.slowDown();
        		}
            }  
		});
		
		// 基本属性
		this.setSize(WIDTH, HEIGHT);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setVisible(true);
		this.setFocusable(true);
		this.setResizable(false);
		timer.start();
	}
	
	/**
	 * 使程序重新获得键盘监听事件
	 */
	private void recoverFocus() {
		this.requestFocus();
	}
	
	class SpeedButtonMouseAdapter extends MouseAdapter {
		
		private int speed;
		
		public SpeedButtonMouseAdapter(int speed) {
			this.speed = speed;
		}

		@Override
		public void mouseClicked(MouseEvent e) {
			targetCar.setSpeed(speed); 
			recoverFocus();
		}
	}
	
	class ViewButtonAdapter extends MouseAdapter {
		
		private String viewType;
		
		public ViewButtonAdapter(String viewType) {
			this.viewType = viewType;
		}

		@Override
		public void mouseClicked(MouseEvent e) {
			if(viewType.equals("跟踪")) {
				HighwayViewer.VIEW_OF_FOLLOW = true;
			} else {
				HighwayViewer.VIEW_OF_FOLLOW = false;
			}
			highwayViewer.setViewMode(viewType);
			recoverFocus();
		}
		
	}
	
	public static void main(String[] args) {
		new CarDrivingSimulator();
	}
	
}
